﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataStuctureStudy.Sorts
{
    /// <summary>
    /// 将数组分为两部分：已排序部分和未排序部分，对数组执行一次遍历，将遍历中的
    /// 当前元素插入到已排序的部分。
    /// 初始状态已排序部分只包括一个元素。
    /// </summary>
    class InsertionSort<T>
        where T : IComparable<T>
    {
        private static void Swap(T[] items, int left, int right)
        {
            if (left != right)
            {
                var temp = items[left];
                items[left] = items[right];
                items[right] = temp;
            }
        }

        public static void Sort(T[] items)
        {
            for (
                var sortedRangeEndIndex = 1;
                sortedRangeEndIndex < items.Length;
                sortedRangeEndIndex++)
            {
                if (items[sortedRangeEndIndex].CompareTo(items[sortedRangeEndIndex - 1]) < 0)
                {
                    int insertIndex = FindInsertionIndex(items, items[sortedRangeEndIndex]);
                    Insert(items, sortedRangeEndIndex, insertIndex);
                }
            }
        }

        private static int FindInsertionIndex(T[] items, T valueToInsert)
        {
            for (var i = 0; i < items.Length; i++)
            {
                if (items[i].CompareTo(valueToInsert) > 0)
                {
                    return i;
                }
            }

            throw new InvalidOperationException();
        }

        private static void Insert(T[] items, int indexInsertingFrom, int indexInsertingAt)
        {
            var temp = items[indexInsertingFrom];

            for (var i = indexInsertingFrom; i > indexInsertingAt; i--)
            {
                items[i] = items[i - 1];
            }

            items[indexInsertingAt] = temp;
        }
    }
}
